package com.wj.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wj.infrastructure.mapper.WeChatUserDO;
import com.wj.infrastructure.mapper.WeChatUserMapper;
import com.wj.service.WechatService;
import com.wj.tool.common.exception.SelfException;
import com.wj.tool.common.utils.HttpClientUtils;
import com.wj.tool.common.utils.StringUtils;
import com.wj.tool.common.utils.UuidUtils;
import com.wj.tool.config.wx.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class WechatServiceImpl implements WechatService {

    private Logger logger = LoggerFactory.getLogger(WechatServiceImpl.class);

    private static final String REQUEST_URL = "https://api.weixin.qq.com/sns/jscode2session";
    private static final String GRANT_TYPE  = "wx_authorization_code";

    @Resource
    private WxProperties wxProperties;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private WeChatUserMapper weChatUserMapper;
  
    @Override
    public Map<String, Object> getUserInfoMap(WechatLoginRequest loginRequest) throws Exception {
        Map<String, Object> userInfoMap = new HashMap<>();
        JSONObject sessionKeyOpenId = getSessionKeyOrOpenId(loginRequest.getCode());

 
        // 获取openId && sessionKey
        String openId = sessionKeyOpenId.getString("openid");

        String sessionKey = sessionKeyOpenId.getString("session_key");
//        WechatUserDO insertOrUpdateDO = buildWechatUserDO(loginRequest, sessionKey, openId);
 
        // 根据code保存openId和sessionKey
        JSONObject sessionObj = new JSONObject();
        sessionObj.put("openId", openId);
        sessionObj.put("sessionKey", sessionKey);
        // 这里的set方法，自行导入自己项目的Redis，key自行替换，这里10表示10天

 
        return userInfoMap;
    }

    @Override
    public Object login(String code) {
        Map resultMap = new HashMap();
        JSONObject jsonObject = getSessionKeyOrOpenId(code);
        if (jsonObject.containsKey("error")){
            resultMap.put("status", 500);
            resultMap.put("msg", "登录失败");
            return resultMap;
        }
        // 获取openId && sessionKey
        String openId = jsonObject.getString("openid");
        String sessionKey = jsonObject.getString("session_key");
        // 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        String signature2 = DigestUtils.sha1Hex(jsonObject + sessionKey);
        /*if (!signature.equals(signature2)) {
            return R.error().message("签名校验失败");
        }*/
        String md5key = DigestUtils.md5Hex(jsonObject + "WX_LOGIN");
        String redisKey = "WX_LOGIN_" +md5key;
        try {
            this.redisTemplate.opsForValue().set(redisKey, jsonObject.toJSONString(), Duration.ofDays(7));
        } catch (Exception e){
            logger.error("redis出错："+ e.getMessage());
        }
        String appId = wxProperties.getAppId();
        String appSecret = wxProperties.getAppSecret();
        jsonObject.put("appId", appId);
        jsonObject.put("appSecret", appSecret);
        return jsonObject;
    }

    /**
     * 保存微信授权信息
     *
     * @param requestVO 微信授权的用户数据
     */
    @Override
    public void saveWeChatUser(UserRequestVO requestVO) {

        WeChatUserDO userDO = weChatUserMapper.getWeChatUserByOpenId(requestVO.getOpenId());

        if (userDO == null) {
            userDO = UserCopyMapping.USER_COPY_MAPPING.requestToDO(requestVO);
            userDO.setId(UuidUtils.createId());
            userDO.setCreateTime(new Date());
            weChatUserMapper.save(userDO);
        }

    }

    /**
     * 保存认证的用户ID
     *
     * @param openId       微信openId
     * @param identityCard 身份证号
     */
//    @Override
    public void updateWeChatUser(String openId, String identityCard, String name, String mobile) {
        weChatUserMapper.updateUserIdentityCard(openId, identityCard, name, mobile);
    }

    @Override
    public UserResponseVO getWeChatUserByIdentityCard(String identityCard) {
        if (StringUtils.isEmpty(identityCard)) {
            throw new SelfException("身份证号不能为空");
        }
        // 微信用户验证
        WeChatUserDO userDO = weChatUserMapper.getWeChatUserByIdentityCard(identityCard);
        return UserCopyMapping.USER_COPY_MAPPING.doToResponse(userDO);
    }

    @Override
    public WeChatUserVO getWeChatUserByOpenId(String openId) {
        WeChatUserVO userVO = null;
        WeChatUserDO userDO = weChatUserMapper.getWeChatUserByOpenId(openId);
        if (Objects.nonNull(userDO)) {
            userVO = new WeChatUserVO();
            BeanUtils.copyProperties(userDO, userVO);
        }
        return userVO;
    }

    private JSONObject getSessionKeyOrOpenId(String code){
        Map<String, String> requestUrlParam = new HashMap<>();
        // 小程序appId，自己补充
        requestUrlParam.put("appid", wxProperties.getAppId());
        // 小程序secret，自己补充
        requestUrlParam.put("secret", wxProperties.getAppSecret());
        // 小程序端返回的code
        requestUrlParam.put("js_code", code);
        // 默认参数
        requestUrlParam.put("grant_type", GRANT_TYPE);
 
        // 发送post请求读取调用微信接口获取openid用户唯一标识
        String result = HttpClientUtils.doPost(REQUEST_URL, requestUrlParam);
        return JSON.parseObject(result);
    }


}